<template>
  <div class="css-formatter">
    <button @click="returnFn" class="btn btn-primary retrunBUtton">
      <i class="icon">⚡</i> 返回
    </button>
    <div class="container">
      <header class="tool-header">
        <h1>CSS 格式化工具</h1>
        <p class="subtitle">美化您的CSS代码，提高可读性和维护性</p>
      </header>

      <div class="tool-content">
        <div class="editor-section">
          <div class="input-panel">
            <div class="panel-header">
              <label>输入CSS代码：</label>
              <div class="action-buttons">
                <button class="format-btn" @click="formatCSS" :disabled="!inputCSS">
                  {{ isFormatted ? '重新格式化' : '格式化CSS' }}
                </button>
                <button class="clear-btn" @click="clearInput">清空</button>
              </div>
            </div>
            <textarea
              v-model="inputCSS"
              placeholder="粘贴CSS代码到这里..."
              rows="15"
              class="css-input"
              :class="{ formatted: isFormatted }"
              spellcheck="false"
            ></textarea>
          </div>

          <div class="output-panel">
            <div class="panel-header">
              <label>格式化结果：</label>
              <div class="action-buttons">
                <button class="copy-btn" @click="copyOutput" :disabled="!formattedCSS">
                  {{ copyButtonText }}
                </button>
                <button class="minify-btn" @click="toggleMinify">
                  {{ showMinified ? '显示美化' : '显示压缩' }}
                </button>
              </div>
            </div>
            <pre
              class="formatted-code"
              v-if="!showMinified"
            ><code>{{ formattedCSS || '格式化后的CSS将显示在这里' }}</code></pre>
            <pre
              class="minified-code"
              v-else
            ><code>{{ minifiedCSS || '压缩后的CSS将显示在这里' }}</code></pre>
          </div>
        </div>

        <div class="options-section">
          <h3>格式化选项</h3>
          <div class="options-grid">
            <div class="option-group">
              <label>缩进类型：</label>
              <div class="radio-group">
                <label class="radio-label">
                  <input type="radio" v-model="formatOptions.indentType" value="spaces" />
                  <span class="radio-custom"></span>
                  空格
                </label>
                <label class="radio-label">
                  <input type="radio" v-model="formatOptions.indentType" value="tabs" />
                  <span class="radio-custom"></span>
                  制表符
                </label>
              </div>
            </div>

            <div class="option-group">
              <label>缩进大小：</label>
              <select v-model="formatOptions.indentSize">
                <option value="2">2 空格</option>
                <option value="4">4 空格</option>
                <option value="8">8 空格</option>
              </select>
            </div>

            <div class="option-group">
              <label>选择器换行：</label>
              <select v-model="formatOptions.selectorSeparator">
                <option value="newline">每个选择器换行</option>
                <option value="space">空格分隔</option>
                <option value="comma">逗号后换行</option>
              </select>
            </div>

            <div class="option-group">
              <label>属性排序：</label>
              <select v-model="formatOptions.propertySorting">
                <option value="none">不排序</option>
                <option value="alphabetical">按字母顺序</option>
                <option value="logical">逻辑分组</option>
              </select>
            </div>

            <div class="option-group">
              <label class="checkbox-label">
                <input type="checkbox" v-model="formatOptions.includeSemicolon" />
                <span class="checkmark"></span>
                最后属性包含分号
              </label>
            </div>

            <div class="option-group">
              <label class="checkbox-label">
                <input type="checkbox" v-model="formatOptions.spaceAroundSelector" />
                <span class="checkmark"></span>
                选择器周围空格
              </label>
            </div>

            <div class="option-group">
              <label class="checkbox-label">
                <input type="checkbox" v-model="formatOptions.breakAfterBrace" />
                <span class="checkmark"></span>
                左大括号后换行
              </label>
            </div>

            <div class="option-group">
              <label class="checkbox-label">
                <input type="checkbox" v-model="formatOptions.autoRgbToHex" />
                <span class="checkmark"></span>
                RGB转十六进制
              </label>
            </div>
          </div>
        </div>

        <div class="stats-section" v-if="formattedCSS">
          <h3>代码统计</h3>
          <div class="stats-grid">
            <div class="stat-item">
              <span class="stat-label">选择器数量</span>
              <span class="stat-value">{{ stats.selectors }}</span>
            </div>
            <div class="stat-item">
              <span class="stat-label">属性数量</span>
              <span class="stat-value">{{ stats.properties }}</span>
            </div>
            <div class="stat-item">
              <span class="stat-label">规则集数量</span>
              <span class="stat-value">{{ stats.rulesets }}</span>
            </div>
            <div class="stat-item">
              <span class="stat-label">文件大小</span>
              <span class="stat-value">{{ stats.fileSize }}</span>
            </div>
            <div class="stat-item">
              <span class="stat-label">压缩后大小</span>
              <span class="stat-value">{{ stats.minifiedSize }}</span>
            </div>
            <div class="stat-item">
              <span class="stat-label">压缩率</span>
              <span class="stat-value">{{ stats.compressionRatio }}%</span>
            </div>
          </div>
        </div>

        <div class="info-section">
          <h3>CSS格式化说明</h3>
          <p>
            CSS格式化工具可以帮助您整理和美化CSS代码，使其具有一致的缩进、空格和结构，提高代码的可读性和可维护性。支持现代CSS特性包括Flexbox、Grid、动画等。
          </p>
        </div>
      </div>

      <footer class="tool-footer">
        <p>© 2023 Vue 3 CSS格式化工具</p>
      </footer>
    </div>
  </div>
</template>

<script setup>
import { ref, computed, watch } from 'vue'
import { useRouter } from 'vue-router'
const inputCSS = ref('')
const formattedCSS = ref('')
const minifiedCSS = ref('')
const isFormatted = ref(false)
const showMinified = ref(false)
const copyButtonText = ref('复制代码')
const Router = useRouter()
const returnFn = () => {
  Router.go(-1)
}
const formatOptions = ref({
  indentType: 'spaces',
  indentSize: 2,
  selectorSeparator: 'newline',
  propertySorting: 'logical',
  includeSemicolon: true,
  spaceAroundSelector: true,
  breakAfterBrace: true,
  autoRgbToHex: true
})

const stats = ref({
  selectors: 0,
  properties: 0,
  rulesets: 0,
  fileSize: '0 B',
  minifiedSize: '0 B',
  compressionRatio: 0
})

// CSS属性逻辑分组顺序
const PROPERTY_GROUPS = [
  // 布局相关
  ['position', 'top', 'right', 'bottom', 'left', 'z-index'],
  // 显示和盒模型
  ['display', 'visibility', 'opacity', 'box-sizing', 'width', 'height', 'min-width', 'min-height', 'max-width', 'max-height'],
  // 弹性布局
  ['flex', 'flex-direction', 'flex-wrap', 'flex-flow', 'justify-content', 'align-items', 'align-content'],
  // 网格布局
  ['grid', 'grid-template-columns', 'grid-template-rows', 'grid-template-areas', 'grid-auto-columns', 'grid-auto-rows'],
  // 边距和填充
  ['margin', 'margin-top', 'margin-right', 'margin-bottom', 'margin-left', 'padding', 'padding-top', 'padding-right', 'padding-bottom', 'padding-left'],
  // 边框
  ['border', 'border-width', 'border-style', 'border-color', 'border-radius', 'outline'],
  // 背景
  ['background', 'background-color', 'background-image', 'background-repeat', 'background-position', 'background-size'],
  // 文字相关
  ['color', 'font', 'font-family', 'font-size', 'font-weight', 'line-height', 'text-align', 'text-decoration', 'text-transform'],
  // 动画和过渡
  ['transition', 'animation', 'transform']
]

const formatCSS = () => {
  if (!inputCSS.value.trim()) {
    formattedCSS.value = ''
    minifiedCSS.value = ''
    isFormatted.value = false
    return
  }

  try {
    const css = inputCSS.value
    const indentChar = formatOptions.value.indentType === 'tabs' ? '\t' : ' '.repeat(parseInt(formatOptions.value.indentSize))

    // 预处理：移除多余空格和注释
    let processedCSS = css
      .replace(/\/\*[\s\S]*?\*\//g, '') // 移除注释
      .replace(/\s+/g, ' ') // 合并多个空格
      .trim()

    // 分割规则集
    const rulesets = splitRulesets(processedCSS)
    let formattedResult = []
    let minifiedResult = []

    stats.value.rulesets = rulesets.length
    stats.value.selectors = 0
    stats.value.properties = 0

    rulesets.forEach(ruleset => {
      const formatted = formatRuleset(ruleset, indentChar)
      const minified = minifyRuleset(ruleset)

      if (formatted) {
        formattedResult.push(formatted)
        minifiedResult.push(minified)
      }
    })

    formattedCSS.value = formattedResult.join('\n\n')
    minifiedCSS.value = minifiedResult.join('')
    isFormatted.value = true

    updateStats()
  } catch (error) {
    console.error('格式化错误:', error)
    formattedCSS.value = '格式化出错，请检查CSS代码语法'
    minifiedCSS.value = ''
    isFormatted.value = false
  }
}

const splitRulesets = (css) => {
  const rulesets = []
  let current = ''
  let depth = 0
  let inString = false
  let stringChar = ''

  for (let i = 0; i < css.length; i++) {
    const char = css[i]

    if (char === '"' || char === "'") {
      if (!inString) {
        inString = true
        stringChar = char
      } else if (char === stringChar) {
        inString = false
      }
    }

    if (!inString) {
      if (char === '{') depth++
      if (char === '}') depth--
    }

    current += char

    if (char === '}' && depth === 0) {
      rulesets.push(current.trim())
      current = ''
    }
  }

  return rulesets.filter(ruleset => ruleset.trim())
}

const formatRuleset = (ruleset, indentChar) => {
  const braceIndex = ruleset.indexOf('{')
  if (braceIndex === -1) return null

  const selectorPart = ruleset.substring(0, braceIndex).trim()
  const contentPart = ruleset.substring(braceIndex + 1, ruleset.length - 1).trim()

  // 处理选择器
  let selectors = []
  if (formatOptions.value.selectorSeparator === 'newline') {
    selectors = selectorPart.split(',').map(s => s.trim()).filter(s => s)
  } else if (formatOptions.value.selectorSeparator === 'comma') {
    selectors = [selectorPart.replace(/,/g, ',\n')]
  } else {
    selectors = [selectorPart]
  }

  // 处理属性
  const properties = contentPart.split(';').filter(prop => prop.trim())
  const sortedProperties = sortProperties(properties.map(prop => prop.trim()))

  stats.value.selectors += selectors.length
  stats.value.properties += sortedProperties.length

  let result = ''

  // 选择器部分
  if (formatOptions.value.spaceAroundSelector) {
    result += selectors.join(',\n') + ' '
  } else {
    result += selectors.join(',\n')
  }

  // 大括号
  if (formatOptions.value.breakAfterBrace) {
    result += '{\n'
  } else {
    result += ' { '
  }

  // 属性部分
  sortedProperties.forEach((prop, index) => {
    const isLast = index === sortedProperties.length - 1
    let formattedProp = prop

    // RGB转十六进制
    if (formatOptions.value.autoRgbToHex && prop.includes('rgb(')) {
      formattedProp = convertRgbToHex(prop)
    }

    if (formatOptions.value.breakAfterBrace) {
      result += indentChar + formattedProp
      if (!isLast || formatOptions.value.includeSemicolon) {
        result += ';'
      }
      result += '\n'
    } else {
      result += formattedProp
      if (!isLast || formatOptions.value.includeSemicolon) {
        result += '; '
      }
    }
  })

  // 闭合大括号
  if (formatOptions.value.breakAfterBrace) {
    result += '}'
  } else {
    result += '}'
  }

  return result
}

const sortProperties = (properties) => {
  if (formatOptions.value.propertySorting === 'none') {
    return properties
  }

  const groupedProperties = []
  const otherProperties = []

  properties.forEach(prop => {
    let added = false

    if (formatOptions.value.propertySorting === 'logical') {
      for (const group of PROPERTY_GROUPS) {
        for (const keyword of group) {
          if (prop.startsWith(keyword + ':') || prop === keyword) {
            if (!groupedProperties[group[0]]) {
              groupedProperties[group[0]] = []
            }
            groupedProperties[group[0]].push(prop)
            added = true
            break
          }
        }
        if (added) break
      }
    }

    if (!added) {
      if (formatOptions.value.propertySorting === 'alphabetical') {
        otherProperties.push(prop)
      } else {
        otherProperties.push(prop)
      }
    }
  })

  let result = []

  if (formatOptions.value.propertySorting === 'logical') {
    PROPERTY_GROUPS.forEach(group => {
      const key = group[0]
      if (groupedProperties[key]) {
        result.push(...groupedProperties[key].sort())
      }
    })
    result.push(...otherProperties.sort())
  } else {
    result = [...properties].sort()
  }

  return result
}

const minifyRuleset = (ruleset) => {
  return ruleset
    .replace(/\s*\{\s*/g, '{')
    .replace(/\s*\}\s*/g, '}')
    .replace(/\s*;\s*/g, ';')
    .replace(/\s*,\s*/g, ',')
    .replace(/\s+/g, ' ')
    .trim()
}

const convertRgbToHex = (property) => {
  return property.replace(/rgb\((\d+),\s*(\d+),\s*(\d+)\)/g, (match, r, g, b) => {
    const hex = '#' +
      parseInt(r).toString(16).padStart(2, '0') +
      parseInt(g).toString(16).padStart(2, '0') +
      parseInt(b).toString(16).padStart(2, '0')
    return hex
  })
}

const updateStats = () => {
  const originalSize = new Blob([inputCSS.value]).size
  const formattedSize = new Blob([formattedCSS.value]).size
  const minifiedSize = new Blob([minifiedCSS.value]).size

  stats.value.fileSize = formatFileSize(formattedSize)
  stats.value.minifiedSize = formatFileSize(minifiedSize)
  stats.value.compressionRatio = Math.round(((formattedSize - minifiedSize) / formattedSize) * 100)
}

const formatFileSize = (bytes) => {
  if (bytes === 0) return '0 B'
  const k = 1024
  const sizes = ['B', 'KB', 'MB', 'GB']
  const i = Math.floor(Math.log(bytes) / Math.log(k))
  return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i]
}

const copyOutput = async () => {
  const textToCopy = showMinified.value ? minifiedCSS.value : formattedCSS.value
  if (!textToCopy) return

  try {
    await navigator.clipboard.writeText(textToCopy)
    copyButtonText.value = '已复制!'
    setTimeout(() => {
      copyButtonText.value = '复制代码'
    }, 2000)
  } catch (err) {
    const textArea = document.createElement('textarea')
    textArea.value = textToCopy
    document.body.appendChild(textArea)
    textArea.select()
    try {
      document.execCommand('copy')
      copyButtonText.value = '已复制!'
      setTimeout(() => {
        copyButtonText.value = '复制代码'
      }, 2000)
    } catch (err2) {
      copyButtonText.value = '复制失败'
      setTimeout(() => {
        copyButtonText.value = '复制代码'
      }, 2000)
    }
    document.body.removeChild(textArea)
  }
}

const toggleMinify = () => {
  showMinified.value = !showMinified.value
}

const clearInput = () => {
  inputCSS.value = ''
  formattedCSS.value = ''
  minifiedCSS.value = ''
  isFormatted.value = false
  showMinified.value = false
}

watch(inputCSS, (newValue) => {
  if (newValue && isFormatted.value) {
    isFormatted.value = false
  }
})

watch(formatOptions, () => {
  if (inputCSS.value && isFormatted.value) {
    formatCSS()
  }
}, { deep: true })
</script>

<style scoped>
.css-formatter {
  min-height: 100vh;
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  padding: 20px;
  font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
  position: relative;
}
.btn {
  padding: 8px 15px;
  border: none;
  border-radius: 6px;
  cursor: pointer;
  font-size: 20px;
  font-weight: 500;
  display: flex;
  align-items: center;
  gap: 5px;
  transition: all 0.3s ease;
}

.btn-primary {
  background: linear-gradient(to right, #667eea, #764ba2);
  color: white;
}
.retrunBUtton {
  position: absolute;
  top: 100px;
  right: 100px;
}
.container {
  max-width: 1200px;
  margin: 0 auto;
  background: white;
  border-radius: 12px;
  box-shadow: 0 10px 30px rgba(0, 0, 0, 0.1);
}

.tool-header {
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  color: white;
  padding: 30px;
  text-align: center;
  border-radius: 12px 12px 0 0;
}

.tool-header h1 {
  margin: 0 0 10px 0;
  font-size: 2.2em;
}

.subtitle {
  margin: 0;
  opacity: 0.9;
  font-size: 1.1em;
}

.tool-content {
  padding: 30px;
}

.editor-section {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 20px;
  margin-bottom: 30px;
}

.input-panel,
.output-panel {
  display: flex;
  flex-direction: column;
}

.panel-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 15px;
}

.panel-header label {
  font-weight: 600;
  color: #333;
  font-size: 20px;
}

.action-buttons {
  display: flex;
  gap: 10px;
}

.format-btn,
.clear-btn,
.copy-btn,
.minify-btn {
  padding: 8px 16px;
  border: none;
  border-radius: 6px;
  font-size: 18px;
  font-weight: 600;
  cursor: pointer;
  transition: all 0.3s;
}

.format-btn {
  background: linear-gradient(to right, #4caf50, #45a049);
  color: white;
}

.format-btn:hover:not(:disabled) {
  transform: translateY(-2px);
  box-shadow: 0 4px 8px rgba(76, 175, 80, 0.3);
}

.format-btn:disabled {
  background: #cccccc;
  cursor: not-allowed;
}

.clear-btn {
  background: #ff9800;
  color: white;
}

.clear-btn:hover {
  background: #f57c00;
  transform: translateY(-2px);
}

.copy-btn {
  background: #2196f3;
  color: white;
}

.copy-btn:hover:not(:disabled) {
  background: #1976d2;
  transform: translateY(-2px);
}

.minify-btn {
  background: #9c27b0;
  color: white;
}

.minify-btn:hover {
  background: #7b1fa2;
  transform: translateY(-2px);
}

button:disabled {
  background: #cccccc;
  cursor: not-allowed;
  transform: none !important;
}

.css-input {
  padding: 15px;
  height: 300px;
  width: 500px;
  border: 2px solid #e0e0e0;
  border-radius: 8px;
  font-size: 18px;
  font-family: 'Courier New', monospace;
  resize: vertical;
  transition: border-color 0.3s;
  background: #f8f9fa;
  line-height: 1.5;
}

.css-input:focus {
  outline: none;
  border-color: #667eea;
}

.css-input.formatted {
  border-color: #4caf50;
}

.formatted-code,
.minified-code {
  width: 500px;
  height: 300px;
  padding: 15px;
  border: 2px solid #e0e0e0;
  border-radius: 8px;
  background: #2d3748;
  color: #e2e8f0;
  font-family: 'Courier New', monospace;
  font-size: 18px;
  overflow: auto;
  white-space: pre-wrap;
  line-height: 1.5;
  margin: 0;
}

.minified-code {
  white-space: pre;
  word-wrap: normal;
}

.options-section {
  margin-bottom: 30px;
}

.options-section h3 {
  margin-bottom: 15px;
  color: #333;
  font-size: 18px;
}

.options-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
  gap: 20px;
  background: #f8f9fa;
  padding: 20px;
  border-radius: 8px;
}

.option-group {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.option-group label {
  font-weight: 600;
  color: #555;
  font-size: 18px;
}

.radio-group {
  display: flex;
  gap: 20px;
}

.radio-label,
.checkbox-label {
  display: flex;
  align-items: center;
  gap: 8px;
  cursor: pointer;
  font-weight: normal;
}

.radio-label input,
.checkbox-label input {
  display: none;
}

.radio-custom {
  width: 18px;
  height: 18px;
  border: 2px solid #ddd;
  border-radius: 50%;
  position: relative;
  transition: all 0.3s;
}

.radio-label input:checked + .radio-custom {
  border-color: #667eea;
}

.radio-label input:checked + .radio-custom::after {
  content: '';
  width: 8px;
  height: 8px;
  background: #667eea;
  border-radius: 50%;
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}

.checkmark {
  width: 18px;
  height: 18px;
  border: 2px solid #ddd;
  border-radius: 3px;
  position: relative;
  transition: all 0.3s;
}

.checkbox-label input:checked + .checkmark {
  background: #667eea;
  border-color: #667eea;
}

.checkbox-label input:checked + .checkmark::after {
  content: '✓';
  position: absolute;
  color: white;
  font-size: 16px;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}

select {
  padding: 8px 12px;
  border: 2px solid #e0e0e0;
  border-radius: 6px;
  font-size: 18px;
  max-width: 200px;
}

select:focus {
  outline: none;
  border-color: #667eea;
}

.stats-section {
  margin-bottom: 30px;
}

.stats-section h3 {
  margin-bottom: 15px;
  color: #333;
  font-size: 18px;
}

.stats-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: 15px;
}

.stat-item {
  background: #f8f9fa;
  padding: 15px;
  border-radius: 6px;
  text-align: center;
  border-left: 4px solid #667eea;
}

.stat-label {
  display: block;
  font-size: 16px;
  color: #666;
  margin-bottom: 5px;
}

.stat-value {
  display: block;
  font-size: 1.5em;
  font-weight: 600;
  color: #333;
}

.info-section {
  background-color: #e3f2fd;
  border-left: 4px solid #2196f3;
  padding: 15px;
  border-radius: 0 8px 8px 0;
}

.info-section h3 {
  color: #1565c0;
  margin-bottom: 10px;
  font-size: 18px;
}

.info-section p {
  color: #424242;
  line-height: 1.6;
  font-size: 18px;
  margin: 0;
}

.tool-footer {
  text-align: center;
  padding: 20px;
  color: #757575;
  font-size: 18px;
  border-top: 1px solid #e0e0e0;
}

@media (max-width: 768px) {
  .editor-section {
    grid-template-columns: 1fr;
  }

  .options-grid {
    grid-template-columns: 1fr;
  }

  .action-buttons {
    flex-direction: column;
  }

  .radio-group {
    flex-direction: column;
    gap: 10px;
  }

  .stats-grid {
    grid-template-columns: repeat(2, 1fr);
  }
}
</style>